package com.gitee.zhuyunlong2018.mybatisplusrelations.handler;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gitee.zhuyunlong2018.mybatisplusrelations.Relations;
import com.gitee.zhuyunlong2018.mybatisplusrelations.binder.IBinder;
import com.gitee.zhuyunlong2018.mybatisplusrelations.config.RelationConfig;
import com.gitee.zhuyunlong2018.mybatisplusrelations.context.IContext;
import com.gitee.zhuyunlong2018.mybatisplusrelations.func.IGetter;
import com.gitee.zhuyunlong2018.mybatisplusrelations.utils.CollectionUtils;
import com.gitee.zhuyunlong2018.mybatisplusrelations.utils.StringUtils;

import java.util.*;
import java.util.function.Consumer;

import static java.util.stream.Collectors.toSet;

public abstract class ListHandler<T, R> extends Handler<T, R> {

    /**
     * 关联主表list
     */
    protected List<T> list;

    public ListHandler(IContext<T> context, IGetter<T, ?> propertyGetter) {
        this.context = context;
        this.list = context.getList();
        this.binder = context.getBinder();
        this.cache = context.getCache(propertyGetter);
    }

    @SuppressWarnings({"unchecked"})
    @Override
    protected LambdaQueryWrapper<R> getQueryWrapper() {
        return null;
    }

    @SuppressWarnings({"unchecked"})
    @Override
    protected LambdaQueryWrapper<R> getQueryWrapper(Collection<?> inParams) {
        // 用批量Id查询用户信息
        LambdaQueryWrapper<R> wrapper = Wrappers.lambdaQuery(cache.getForeignEntityClass())
                .in(cache.getForeignPropertyGetter(), inParams);
        wrapper.apply(!StringUtils.isEmpty(cache.getApplySql()), cache.getApplySql());
        if (lambdaWrapperFunc != null) {
            lambdaWrapperFunc.accept(wrapper);
        }
        wrapper.last(!StringUtils.isEmpty(cache.getLastSql()), cache.getLastSql());
        return wrapper;
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    @Override
    protected void queryRelation() {
        if (foreignEntityList == null) {
            // 准备deptId方便批量查询用户信息
            Set<?> localProperties = list.stream()
                    .map(s -> cache.getLocalPropertyGetter().apply(s))
                    .filter(Objects::nonNull)
                    .collect(toSet());
            if (localProperties.isEmpty()) {
                return;
            }
            List list = new ArrayList();
            if (RelationConfig.shouldLoop(localProperties)) {
                Collection<? extends Collection<?>> collections = CollectionUtils.subCollection(localProperties, RelationConfig.LOOP_MAX_IN_PARAMS);
                foreignEntityList = new ArrayList<>();
                for (Collection<?> collection : collections) {
                    if (collection.isEmpty()) {
                        break;
                    }
                    list.addAll(
                            getForeignModel()
                                    .selectList((LambdaQueryWrapper) getQueryWrapper(collection))
                    );
                }
            } else {
                list = getForeignModel()
                        .selectList((LambdaQueryWrapper) getQueryWrapper(localProperties));
            }
            foreignEntityList = covertListModelToVO(list);
        }
    }

    @Override
    public IBinder<T> deepWith(Consumer<IBinder<R>> binderConsumer) {
        deepBinderConsumer = binderConsumer;
        return binder;
    }

    @Override
    protected IBinder<R> deepBinder() {
        return Relations.with(foreignEntityList);
    }

    @Override
    public IHandler<T, R> setForeignData(List<R> foreignList) {
        foreignEntityList = foreignList;
        return this;
    }

}
